﻿using Godot.core.io;
using Godot.core.os;
using Godot.core.bind;

using Godot.scene;
using Godot.scene.main;

namespace Godot.core
{
    public static class Register
    {
        public static TranslationLoaderPO resource_loader_po = null;

        public static ResourceFormatSaverBinary resource_saver_binary = null;

        public static ResourceFormatLoaderBinary resource_loader_binary = null;

        public static ResourceFormatSaverXML resource_saver_xml = null;

        public static ResourceFormatLoaderXML resource_loader_xml = null;

        public static CoreBindGeometry geometry = null;

        public static CoreBindResourceLoader resource_loader = null;

        public static CoreBindResourceSaver resource_saver = null;

        public static CoreBindOS os = null;

        public static CoreBindMarshalls marshalls = null;

        public static void register_core_types()
        {
            //_global_mutex=Mutex::create();

            StringName.setup();

            Variant.register_variant_methods();

            CoreStringNames.create();

            Register.resource_loader_po = new TranslationLoaderPO();
            ResourceLoader.add_resource_format_loader(resource_loader_po);

            resource_saver_binary = new ResourceFormatSaverBinary();
	        ResourceSaver.add_resource_format_saver(resource_saver_binary);

            resource_loader_binary = new ResourceFormatLoaderBinary();
            ResourceLoader.add_resource_format_loader(resource_loader_binary);

            resource_saver_xml = new ResourceFormatSaverXML();
            ResourceSaver.add_resource_format_saver(resource_saver_xml);

            resource_loader_xml = new ResourceFormatLoaderXML();
            ResourceLoader.add_resource_format_loader(resource_loader_xml);

            ObjectTypeDB.register_type<Object>();
            ObjectTypeDB.register_type<ResourceImportMetadata>();
            ObjectTypeDB.register_type<Resource>();
            
            //ObjectTypeDB::register_virtual_type<StreamPeer>();
	        //ObjectTypeDB::register_create_type<StreamPeerTCP>();
	        //ObjectTypeDB::register_create_type<TCP_Server>();
	        //ObjectTypeDB::register_virtual_type<IP>();
	        //ObjectTypeDB::register_virtual_type<PacketPeer>();
	        //ObjectTypeDB::register_type<PacketPeerStream>();
	        
            ObjectTypeDB.register_type<MainLoop>();
       
	        ObjectTypeDB.register_type<Translation>();
	        ObjectTypeDB.register_type<PHashTranslation>();

	        //ObjectTypeDB::register_type<HTTPClient>();

	        ObjectTypeDB.register_virtual_type<ResourceInteractiveLoader>();

	        ObjectTypeDB.register_type<File>();
	        ObjectTypeDB.register_type<Directory>();
	        ObjectTypeDB.register_type<CoreBindThread>();
	        ObjectTypeDB.register_type<Mutex>();
	        ObjectTypeDB.register_type<Semaphore>();

	        ObjectTypeDB.register_type<XMLParser>();

	        ObjectTypeDB.register_type<ConfigFile>();

	        ObjectTypeDB.register_type<PackedDataContainer>();
	        ObjectTypeDB.register_virtual_type<PackedDataContainerRef>();

            //ip = IP::create();

            geometry = new CoreBindGeometry();

            resource_loader = new CoreBindResourceLoader();

            resource_saver = new CoreBindResourceSaver();

            os = new CoreBindOS();

            marshalls = new CoreBindMarshalls();
        }

        public static void register_core_singletons() 
        {
	        Globals.singleton.add_singleton(new Globals.Singleton("Globals", Globals.singleton));
	        //Globals.singleton.add_singleton(new Globals.Singleton("IP", IP.singleton));
	        //Globals.singleton.add_singleton(new Globals.Singleton("Geometry",_Geometry::get_singleton()) );
	        Globals.singleton.add_singleton(new Globals.Singleton("ResourceLoader",CoreBindResourceLoader.singleton) );
	        Globals.singleton.add_singleton(new Globals.Singleton("ResourceSaver", CoreBindResourceSaver.singleton) );
	        Globals.singleton.add_singleton(new Globals.Singleton("PathRemap",PathRemap.singleton));
	        Globals.singleton.add_singleton(new Globals.Singleton("OS", CoreBindOS.singleton));
	        Globals.singleton.add_singleton( new Globals.Singleton("Marshalls", marshalls ) );
	        Globals.singleton.add_singleton(new Globals.Singleton("TranslationServer",TranslationServer.singleton));
	        Globals.singleton.add_singleton(new Globals.Singleton("TS",TranslationServer.singleton));
	        Globals.singleton.add_singleton(new Globals.Singleton("Input", Input.singleton));

        }

        public static void register_scene_types()
        {
            SceneStringNames.create();
            ObjectTypeDB.register_type<SceneMainLoop>();
        }

        public static void register_server_types()
        {
            //throw new System.NotImplementedException();
        }

        public static void register_module_types()
        {
            //throw new System.NotImplementedException();
        }

        public static void register_driver_types()
        {
            //throw new System.NotImplementedException();
        }
    }
}